﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace USMCdotNET
{
    public struct Vector<Type>
        where Type : struct
    {
        private Type x;
        private Type y;
        private Func<Type, Type, Type> add;
        private Func<Type, Type, Type> mult;
        private Func<Type, Type> sqrt;
        public Type X
        {
            get
            { return x; }
            set
            { x = value; }
        }
        public Type Y
        {
            get
            { return y; }
            set
            { y = value; }
        }
        public Type Length
        {
            get
            {
                return sqrt(add(mult(x, x), mult(y, y)));
            }
        }
        public override string ToString()
        {
            return '(' + x.ToString() + ", " + y.ToString() + ')';
        }
        public Vector(Type x, Type y, Func<Type, Type, Type> addition, Func<Type, Type, Type> multiplication, Func<Type, Type> sqrt)
        {
            this.x = x;
            this.y = y;
            add = addition;
            mult = multiplication;
            this.sqrt = sqrt;
        }
        public void Change(Type x1, Type y1)
        {
            x = x1;
            y = y1;
        }
        public Vector<Type> Multiplicate(Type scalar)
        {
            return new Vector<Type>(mult(x, scalar), mult(y, scalar), add, mult, sqrt);
        }
        public static Vector<Type> operator *(Vector<Type> vector, Type scalar)
        {
            return vector.Multiplicate(scalar);
        }
        public static Vector<Type> operator *(Type scalar, Vector<Type> vector)
        {
            return vector.Multiplicate(scalar);
        }
        public Vector<Type> Add(Vector<Type> vector)
        {
            return new Vector<Type>(add(x, vector.x), add(y, vector.y), add, mult, sqrt);
        }
        public static Vector<Type> operator +(Vector<Type> v1, Vector<Type> v2)
        {
            return v1.Add(v2);
        }
    }
}
